﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Security;
using System.Threading;
using System.Windows;
using System.Windows.Media;

using Microsoft.Coding4Fun.TweetCraft.Wow;
using Microsoft.SqlServer.MessageBox;

namespace Microsoft.Coding4Fun.TweetCraft.Tray
{
    // ReSharper disable UnusedMember.Global
    // ReSharper disable MemberCanBePrivate.Global
    internal sealed class SettingsContext : INotifyPropertyChanged
    {
        private readonly IWorldOfWarcraft worldOfWarcraft = new WorldOfWarcraft();

        private bool isValidatingAccount;
        private bool? isAccountValid;

        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public string TwitterToken
        {
            get { return Settings.Default.TwitterToken; }
            set
            {
                if (Settings.Default.TwitterToken != value)
                {
                    Settings.Default.TwitterToken = value;
                    OnPropertyChanged("TwitterToken");

                    this.IsAccountValid = null;
                    this.TwitterTokenSecret = String.Empty;
                }
            }
        }

        public string TwitterTokenSecret
        {
            get { return Settings.Default.TwitterTokenSecret; }
            set
            {
                if (Settings.Default.TwitterTokenSecret != value)
                {
                    Settings.Default.TwitterTokenSecret = value;
                    OnPropertyChanged("TwitterTokenSecret");

                    this.ValidateAccount();
                }
            }
        }

        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public bool IsValidatingAccount
        {
            get { return isValidatingAccount; }
            private set
            {
                if (isValidatingAccount != value)
                {
                    isValidatingAccount = value;
                    OnPropertyChanged("IsValidatingAccount");
                    OnPropertyChanged("TwitterValidationStatus");
                    OnPropertyChanged("TwitterValidationStatusForeground");
                }
            }
        }

        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public bool? IsAccountValid
        {
            get { return isAccountValid; }
            private set
            {
                if (isAccountValid != value)
                {
                    isAccountValid = value;
                    OnPropertyChanged("IsAccountValid");
                    OnPropertyChanged("TwitterValidationStatus");
                    OnPropertyChanged("TwitterValidationStatusForeground");
                }
            }
        }

        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public string TwitterValidationStatus
        {
            get
            {
                if (isValidatingAccount)
                    return Strings.ValidatingTwitterAccount;

                if (!IsAccountValid.HasValue)
                    return String.Empty;

                return IsAccountValid.Value ? Strings.TwitterAcountValid : Strings.TwitterAccountInvalid;
            }
        }

        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public Brush TwitterValidationStatusForeground
        {
            get
            {
                return !isValidatingAccount && IsAccountValid == true ? Brushes.DarkGreen : Brushes.DarkRed;
            }
        }


        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public ICollection<string> WowAccounts
        {
            get { return worldOfWarcraft.GetAccountNames(); }
        }

        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public static bool AutoTweetScreenshots
        {
            get { return Settings.Default.AutoTweetScreenshots; }
            set { Settings.Default.AutoTweetScreenshots = value; }
        }

        [SuppressMessage("Microsoft.Performance", "CA1811", Justification = "Property is used for data binding.")]
        public static string WowAccount
        {
            get { return Settings.Default.WowAccount; }
            set { Settings.Default.WowAccount = value; }
        }

        public static void Cancel()
        {
            Settings.Default.Reload();
        }

        public static void Apply()
        {
            Settings.Default.Save();
        }

        private void ValidateAccount()
        {
            if(TwitterToken.Equals("?"))
            {
                TwitterToken = string.Empty;
                IsAccountValid = false;
            }

            // Only try to validate account if both token and secret are available
            if (!String.IsNullOrEmpty(TwitterToken) && !String.IsNullOrEmpty(TwitterTokenSecret))
            {
                // Queue a validation on the thread pool
                ThreadPool.QueueUserWorkItem(ValidateCallback, new Credentials 
                                                    { 
                                                        Token = TwitterToken, 
                                                        TokenSecret = TwitterTokenSecret.ToSecureString()
                                                    });
            }
        }

        private void ValidateCallback(object state)
        {
            var credentials = (Credentials)state;

            // Signal that we are in the process of validating the account
            IsValidatingAccount = true;

            try
            {
                // Validate the credentials using the Twitter class
                IsAccountValid = Twitter.TwitterClient.ValidateAccount(credentials.Token, credentials.TokenSecret);
            }
            catch (WebException)
            {
                // Could not validate account
                TweetCraftApplication.ShowMessageBox(Strings.CouldNotValidateAccount, Strings.TweetCraftTitle, ExceptionMessageBoxButtons.OK, ExceptionMessageBoxSymbol.Error);

                IsAccountValid = null;
            }

            // Signal that validation ended
            IsValidatingAccount = false;
        }

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        // Nested class used to pass the username and password to be validated
        class Credentials
        {
            public string Token { get; set; }
            public SecureString TokenSecret { get; set; }
        }
    }
    // ReSharper restore UnusedMember.Global
    // ReSharper restore MemberCanBePrivate.Global
}
